package com.gitee.wsl.base


/**
 * Description: 扩展元组
 * @author Junerver
 * date: 2024/2/7-13:23
 * Email: junerver@gmail.com
 * Version: v1.0
 */
typealias Tuple2<A, B> = Pair<A, B>
typealias Tuple3<A, B, C> = Triple<A, B, C>
typealias Tuple4<A, B, C, D> = Quadruple<A, B, C, D>
typealias Tuple5<A, B, C, D, E> = Quintuple<A, B, C, D, E>
typealias Tuple6<A, B, C, D, E, F> = Sextuple<A, B, C, D, E, F>
typealias Tuple7<A, B, C, D, E, F, G> = Septuple<A, B, C, D, E, F, G>
typealias Tuple8<A, B, C, D, E, F, G, H> = Octuple<A, B, C, D, E, F, G, H>
typealias Tuple9<A, B, C, D, E, F, G, H, I> = Nonuple<A, B, C, D, E, F, G, H, I>
typealias Tuple10<A, B, C, D, E, F, G, H, I, J> = Decuple<A, B, C, D, E, F, G, H, I, J>

interface Tuple{
    companion object
}

inline fun <reified A, reified B> Tuple.Companion.of(a:A, b: B) = tuple(a,b)

inline fun <reified A, reified B, reified C> Tuple.Companion.of(a:A, b: B,c:C) = tuple(a,b,c)

inline fun <reified A, reified B, reified C, reified D> Tuple.Companion.of(a:A, b: B,c:C,d:D) = tuple(a,b,c,d)

/**
 * 四个数据的元组类型
 */
data class Quadruple<out A, out B, out C, out D>(
    val first: A,
    val second: B,
    val third: C,
    val fourth: D
) : Tuple {
     override fun toString(): String = "($first, $second, $third, $fourth)"
}

 fun <T> Quadruple<T, T, T, T>.toList(): List<T> = listOf(first, second, third, fourth)

/**
 * 五个数据的元组类型
 */
data class Quintuple<out A, out B, out C, out D, out E>(
    val first: A,
    val second: B,
    val third: C,
    val fourth: D,
    val fifth: E
) : Tuple {
     override fun toString(): String = "($first, $second, $third, $fourth, $fifth)"
}

 fun <T> Quintuple<T, T, T, T, T>.toList(): List<T> =
    listOf(first, second, third, fourth, fifth)

/**
 * 六个数据的元组类型
 */
data class Sextuple<out A, out B, out C, out D, out E, out F>(
    val first: A,
    val second: B,
    val third: C,
    val fourth: D,
    val fifth: E,
    val sixth: F
) : Tuple {
     override fun toString(): String = "($first, $second, $third, $fourth, $fifth, $sixth)"
}

 fun <T> Sextuple<T, T, T, T, T, T>.toList(): List<T> =
    listOf(first, second, third, fourth, fifth, sixth)

/**
 * 七个数据的元组类型
 */
data class Septuple<out A, out B, out C, out D, out E, out F, out G>(
    val first: A,
    val second: B,
    val third: C,
    val fourth: D,
    val fifth: E,
    val sixth: F,
    val seventh: G
) : Tuple {
     override fun toString(): String =
        "($first, $second, $third, $fourth, $fifth, $sixth, $seventh)"
}

 fun <T> Septuple<T, T, T, T, T, T, T>.toList(): List<T> =
    listOf(first, second, third, fourth, fifth, sixth, seventh)

/**
 * 八个数据的元组类型
 */
data class Octuple<out A, out B, out C, out D, out E, out F, out G, out H>(
    val first: A,
    val second: B,
    val third: C,
    val fourth: D,
    val fifth: E,
    val sixth: F,
    val seventh: G,
    val eighth: H
) : Tuple {
     override fun toString(): String =
        "($first, $second, $third, $fourth, $fifth, $sixth, $seventh, $eighth)"
}

 fun <T> Octuple<T, T, T, T, T, T, T, T>.toList(): List<T> =
    listOf(first, second, third, fourth, fifth, sixth, seventh, eighth)

/**
 * 九个数据的元组类型
 */
data class Nonuple<out A, out B, out C, out D, out E, out F, out G, out H, out I>(
    val first: A,
    val second: B,
    val third: C,
    val fourth: D,
    val fifth: E,
    val sixth: F,
    val seventh: G,
    val eighth: H,
    val ninth: I
) : Tuple {
     override fun toString(): String =
        "($first, $second, $third, $fourth, $fifth, $sixth, $seventh, $eighth, $ninth)"
}

 fun <T> Nonuple<T, T, T, T, T, T, T, T, T>.toList(): List<T> =
    listOf(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth)

/**
 * 十个数据的元组类型
 */
data class Decuple<out A, out B, out C, out D, out E, out F, out G, out H, out I, out J>(
    val first: A,
    val second: B,
    val third: C,
    val fourth: D,
    val fifth: E,
    val sixth: F,
    val seventh: G,
    val eighth: H,
    val ninth: I,
    val tenth: J
) : Tuple {
     override fun toString(): String =
        "($first, $second, $third, $fourth, $fifth, $sixth, $seventh, $eighth, $ninth, $tenth)"
}

 fun <T> Decuple<T, T, T, T, T, T, T, T, T, T>.toList(): List<T> =
    listOf(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth)


data class Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(val t1: T1, val t2: T2, val t3: T3, val t4: T4, val t5: T5, val t6: T6, val t7: T7, val t8: T8, val t9: T9, val t10: T10, val t11: T11) : Tuple
val <T, T1 : T, T2 : T, T3 : T, T4 : T, T5 : T, T6 : T, T7 : T, T8 : T, T9 : T, T10 : T, T11 : T> Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>.components: List<T> get() = listOf(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11)

data class Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(val t1: T1, val t2: T2, val t3: T3, val t4: T4, val t5: T5, val t6: T6, val t7: T7, val t8: T8, val t9: T9, val t10: T10, val t11: T11, val t12: T12) : Tuple
val <T, T1 : T, T2 : T, T3 : T, T4 : T, T5 : T, T6 : T, T7 : T, T8 : T, T9 : T, T10 : T, T11 : T, T12 : T> Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>.components: List<T> get() = listOf(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12)

data class Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(val t1: T1, val t2: T2, val t3: T3, val t4: T4, val t5: T5, val t6: T6, val t7: T7, val t8: T8, val t9: T9, val t10: T10, val t11: T11, val t12: T12, val t13: T13) : Tuple
val <T, T1 : T, T2 : T, T3 : T, T4 : T, T5 : T, T6 : T, T7 : T, T8 : T, T9 : T, T10 : T, T11 : T, T12 : T, T13 : T> Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>.components: List<T> get() = listOf(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13)

data class Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(val t1: T1, val t2: T2, val t3: T3, val t4: T4, val t5: T5, val t6: T6, val t7: T7, val t8: T8, val t9: T9, val t10: T10, val t11: T11, val t12: T12, val t13: T13, val t14: T14) : Tuple
val <T, T1 : T, T2 : T, T3 : T, T4 : T, T5 : T, T6 : T, T7 : T, T8 : T, T9 : T, T10 : T, T11 : T, T12 : T, T13 : T, T14 : T> Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>.components: List<T> get() = listOf(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14)

data class Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(val t1: T1, val t2: T2, val t3: T3, val t4: T4, val t5: T5, val t6: T6, val t7: T7, val t8: T8, val t9: T9, val t10: T10, val t11: T11, val t12: T12, val t13: T13, val t14: T14, val t15: T15) : Tuple
val <T, T1 : T, T2 : T, T3 : T, T4 : T, T5 : T, T6 : T, T7 : T, T8 : T, T9 : T, T10 : T, T11 : T, T12 : T, T13 : T, T14 : T, T15 : T> Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>.components: List<T> get() = listOf(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15)

data class Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(val t1: T1, val t2: T2, val t3: T3, val t4: T4, val t5: T5, val t6: T6, val t7: T7, val t8: T8, val t9: T9, val t10: T10, val t11: T11, val t12: T12, val t13: T13, val t14: T14, val t15: T15, val t16: T16) : Tuple
val <T, T1 : T, T2 : T, T3 : T, T4 : T, T5 : T, T6 : T, T7 : T, T8 : T, T9 : T, T10 : T, T11 : T, T12 : T, T13 : T, T14 : T, T15 : T, T16 : T> Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>.components: List<T> get() = listOf(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16)



/**
 * 元组扩展，可以使用 `a to b to c` 这样的连续中缀函数创建更多元素的元组
 */
infix fun <A, B, C> Pair<A, B>.to(c: C): Triple<A, B, C> = Triple(this.first, this.second, c)

infix fun <A, B, C, D> Triple<A, B, C>.to(d: D): Quadruple<A, B, C, D> =
    Quadruple(this.first, this.second, this.third, d)

infix fun <A, B, C, D, E> Quadruple<A, B, C, D>.to(e: E): Quintuple<A, B, C, D, E> =
    Quintuple(this.first, this.second, this.third, this.fourth, e)

infix fun <A, B, C, D, E, F> Quintuple<A, B, C, D, E>.to(f: F): Sextuple<A, B, C, D, E, F> =
    Sextuple(this.first, this.second, this.third, this.fourth, this.fifth, f)

infix fun <A, B, C, D, E, F, G> Sextuple<A, B, C, D, E, F>.to(g: G): Septuple<A, B, C, D, E, F, G> =
    Septuple(this.first, this.second, this.third, this.fourth, this.fifth, this.sixth, g)

infix fun <A, B, C, D, E, F, G, H> Septuple<A, B, C, D, E, F, G>.to(h: H): Octuple<A, B, C, D, E, F, G, H> =
    Octuple(
        this.first,
        this.second,
        this.third,
        this.fourth,
        this.fifth,
        this.sixth,
        this.seventh,
        h
    )

infix fun <A, B, C, D, E, F, G, H, I> Octuple<A, B, C, D, E, F, G, H>.to(i: I): Nonuple<A, B, C, D, E, F, G, H, I> =
    Nonuple(
        this.first,
        this.second,
        this.third,
        this.fourth,
        this.fifth,
        this.sixth,
        this.seventh,
        this.eighth,
        i
    )

infix fun <A, B, C, D, E, F, G, H, I, J> Nonuple<A, B, C, D, E, F, G, H, I>.to(j: J): Decuple<A, B, C, D, E, F, G, H, I, J> =
    Decuple(
        this.first,
        this.second,
        this.third,
        this.fourth,
        this.fifth,
        this.sixth,
        this.seventh,
        this.eighth,
        this.ninth,
        j
    )

operator fun <A, B, C> Pair<A, B>.plus(c: C): Triple<A, B, C> = Triple(this.first, this.second, c)
operator fun <A, B, C, D> Triple<A, B, C>.plus(d: D): Tuple4<A, B, C, D> = Tuple4(this.first, this.second, this.third, d)
operator fun <A, B, C, D, E> Tuple4<A, B, C, D>.plus(e: E): Tuple5<A, B, C, D, E> = Tuple5(this.first, this.second, this.third, this.fourth, e)
operator fun <A, B, C, D, E, F> Tuple5<A, B, C, D, E>.plus(f: F): Tuple6<A, B, C, D, E, F> = Tuple6(this.first, this.second, this.third, this.fourth, this.fifth, f)
operator fun <A, B, C, D, E, F, G> Tuple6<A, B, C, D, E, F>.plus(g: G): Tuple7<A, B, C, D, E, F, G> = Tuple7(this.first, this.second, this.third, this.fourth, this.fifth, this.sixth, g)
operator fun <A, B, C, D, E, F, G, H> Tuple7<A, B, C, D, E, F, G>.plus(h: H): Tuple8<A, B, C, D, E, F, G, H> = Tuple8(this.first, this.second, this.third, this.fourth, this.fifth, this.sixth, this.seventh, h)
operator fun <A, B, C, D, E, F, G, H, I> Tuple8<A, B, C, D, E, F, G, H>.plus(i: I): Tuple9<A, B, C, D, E, F, G, H, I> = Tuple9(this.first, this.second, this.third, this.fourth, this.fifth, this.sixth, this.seventh, this.eighth, i)
operator fun <A, B, C, D, E, F, G, H, I, J> Tuple9<A, B, C, D, E, F, G, H, I>.plus(j: J): Tuple10<A, B, C, D, E, F, G, H, I, J> = Tuple10(this.first, this.second, this.third, this.fourth, this.fifth, this.sixth, this.seventh, this.eighth, this.ninth, j)


inline fun <reified A, reified B> tuple(first: A, second: B): Tuple2<A, B> =
    Tuple2(first, second)

inline fun <reified A, reified B, reified C> tuple(first: A, second: B, third: C): Tuple3<A, B, C> =
    Tuple3(first, second, third)

inline fun <reified A, reified B, reified C, reified D> tuple(
    first: A,
    second: B,
    third: C,
    fourth: D
): Tuple4<A, B, C, D> =
    Tuple4(first, second, third, fourth)

inline fun <reified A, reified B, reified C, reified D, reified E> tuple(
    first: A,
    second: B,
    third: C,
    fourth: D,
    fifth: E
): Tuple5<A, B, C, D, E> = Tuple5(first, second, third, fourth, fifth)

inline fun <reified A, reified B, reified C, reified D, reified E, reified F> tuple(
    first: A,
    second: B,
    third: C,
    fourth: D,
    fifth: E,
    sixth: F
): Tuple6<A, B, C, D, E, F> = Tuple6(first, second, third, fourth, fifth, sixth)

inline fun <reified A, reified B, reified C, reified D, reified E, reified F, reified G> tuple(
    first: A,
    second: B,
    third: C,
    fourth: D,
    fifth: E,
    sixth: F,
    seventh: G
): Tuple7<A, B, C, D, E, F, G> = Tuple7(first, second, third, fourth, fifth, sixth, seventh)

inline fun <reified A, reified B, reified C, reified D, reified E, reified F, reified G, reified H> tuple(
    first: A,
    second: B,
    third: C,
    fourth: D,
    fifth: E,
    sixth: F,
    seventh: G,
    eighth: H
): Tuple8<A, B, C, D, E, F, G, H> =
    Tuple8(first, second, third, fourth, fifth, sixth, seventh, eighth)

inline fun <reified A, reified B, reified C, reified D, reified E, reified F, reified G, reified H, reified I> tuple(
    first: A,
    second: B,
    third: C,
    fourth: D,
    fifth: E,
    sixth: F,
    seventh: G,
    eighth: H,
    ninth: I
): Tuple9<A, B, C, D, E, F, G, H, I> =
    Tuple9(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth)

inline fun <reified A, reified B, reified C, reified D, reified E, reified F, reified G, reified H, reified I, reified J> tuple(
    first: A,
    second: B,
    third: C,
    fourth: D,
    fifth: E,
    sixth: F,
    seventh: G,
    eighth: H,
    ninth: I,
    tenth: J
): Tuple10<A, B, C, D, E, F, G, H, I, J> =
    Tuple10(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth)

fun <T1, T2, R> Tuple2<T1, T2>.map(block: (T1, T2) -> R): R = block(first, second)

fun <T1, T2, T3, R> Tuple3<T1, T2, T3>.map(block: (T1, T2, T3) -> R): R = block(first, second, third)

fun <T1, T2, T3, T4, R> Tuple4<T1, T2, T3, T4>.map(block: (T1, T2, T3, T4) -> R): R = block(first, second, third, fourth)

fun <T1, T2, T3, T4, T5, R> Tuple5<T1, T2, T3, T4, T5>.map(block: (T1, T2, T3, T4, T5) -> R): R =
    block(first, second, third, fourth, fifth)

fun <T1, T2, T3, T4, T5, T6, R> Tuple6<T1, T2, T3, T4, T5, T6>.map(block: (T1, T2, T3, T4, T5, T6) -> R): R =
    block(first, second, third, fourth, fifth, sixth)

fun <T1, T2, T3, T4, T5, T6, T7, R> Tuple7<T1, T2, T3, T4, T5, T6, T7>.map(block: (T1, T2, T3, T4, T5, T6, T7) -> R): R =
    block(first, second, third, fourth, fifth, sixth, seventh)

fun <T1, T2, T3, T4, T5, T6, T7, T8, R> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>.map(block: (T1, T2, T3, T4, T5, T6, T7, T8) -> R): R =
    block(first, second, third, fourth, fifth, sixth, seventh, eighth)

fun <T1, T2, T3, T4, T5, T6, T7, T8, T9, R> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9>.map(block: (T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R): R =
    block(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth)

fun <A, B, C, D, E, F, G, H, I, J,R> Tuple10<A, B, C, D, E, F, G, H, I, J>.map(block: (A, B, C, D, E, F, G, H, I, J) -> R) =
    block(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth)